using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;

namespace Home.Controls
{
    [ToolboxData("<{0}:TreeListView runat=server></{0}:TreeListView>")]
    public class TreeListView : CompositeDataBoundControl
    {
        #region Fileds

        private ITemplate m_Template;
        private ITemplate m_HeaderTemplate;
        private ITemplate m_FooterTemplate;
        private List<TreeListNode> m_nodes;
        private int m_nIndex;
        private TreeListNode m_DataSource;

        #endregion

        #region Properties

        //[Bindable(true)]
        //[Category("Appearance")]
        //[DefaultValue("")]
        //[Localizable(true)]
        //public string Text
        //{
        //    get
        //    {
        //        String s = (String)ViewState["Text"];
        //        return ((s == null) ? String.Empty : s);
        //    }

        //    set
        //    {
        //        ViewState["Text"] = value;
        //    }
        //}

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        public string Prefix
        {
            get
            {
                String s = (String)ViewState["Prefix"];

                return ((s == null || s == String.Empty) ? this.ID : s);
            }

            set
            {
                ViewState["Prefix"] = value;
            }
        }

        [Browsable(true)]
        [TemplateContainer(typeof(TreeListViewTemplate))]
        public ITemplate ItemTemplate
        {
            get { return m_Template; }
            set { m_Template = value; }
        }

        [Browsable(true)]
        [TemplateContainer(typeof(TreeListItem))]
        public ITemplate HeaderTemplate
        {
            get { return m_HeaderTemplate; }
            set { m_HeaderTemplate = value; }
        }

        [Browsable(true)]
        [TemplateContainer(typeof(TreeListItem))]
        public ITemplate FooterTemplate
        {
            get { return m_FooterTemplate; }
            set { m_FooterTemplate = value; }
        }

        private bool m_IsShowRootNode = true;
        public bool IsShowRootNode
        {
            get { return m_IsShowRootNode; }
            set { m_IsShowRootNode = value; }
        }

        private bool m_IsShowLines = true;
        public bool IsShowLines
        {
            get { return m_IsShowLines; }
            set { m_IsShowLines = value; }
        }

        private int m_ExpandDepth = 3;
        /// <summary>
        /// TreeListView ExpandDepth(default value is 3)
        /// </summary>
        public int ExpandDepth
        {
            get { return m_ExpandDepth; }
            set { m_ExpandDepth = value; }
        }

        private string m_ImageHorizontal;
        public string ImageHorizontal
        {
            get { return m_ImageHorizontal; }
            set { m_ImageHorizontal = value; }
        }

        private string m_ImageVertial;
        public string ImageVertial
        {
            get { return m_ImageVertial; }
            set { m_ImageVertial = value; }
        }

        private string m_ImageExpand;
        public string ImageExpand
        {
            get { return m_ImageExpand; }
            set { m_ImageExpand = value; }
        }

        private string m_ImageCollapse;
        public string ImageCollapse
        {
            get { return m_ImageCollapse; }
            set { m_ImageCollapse = value; }
        }

        public int TotalNodeNumber
        {
            get { return m_nIndex; }
        }

        #endregion

        #region Overrides

        public override object DataSource
        {
            get
            {
                return m_DataSource;
            }
            set
            {
                m_DataSource = (TreeListNode)value;
            }
        }

        public TreeListNode Root
        {
            get
            {
                return m_DataSource;
            }
            set
            {
                m_DataSource = value;
            }
        }

        public override void DataBind()
        {
            this.ImageCollapse  = Page.ClientScript.GetWebResourceUrl(typeof(TreeListView), "Home.Controls.Rescources.Collapse.gif");
            this.ImageExpand    = Page.ClientScript.GetWebResourceUrl(typeof(TreeListView), "Home.Controls.Rescources.Expand.gif");
            this.ImageHorizontal= Page.ClientScript.GetWebResourceUrl(typeof(TreeListView), "Home.Controls.Rescources.TreeViewList_Horizontal.gif");
            this.ImageVertial   = Page.ClientScript.GetWebResourceUrl(typeof(TreeListView), "Home.Controls.Rescources.TreeViewList_Vertical.gif");
            
            Page.ClientScript.RegisterClientScriptBlock(typeof(TreeListView), "Home.Controls.Rescources", "var TreeListView_Collapse=\"" + ImageCollapse + "\";\r\nvar TreeListView_Expand=\"" + ImageExpand + "\";\r\n", true);
            Page.ClientScript.RegisterClientScriptResource(typeof(TreeListView), "Home.Controls.Rescources.TreeListView.js");
            TreeListNode nodes = this.Root;

            if (nodes!=null)
            {
                AddNode(null, nodes,true);
            }

            base.DataSource = this.m_nodes;
            base.DataBind();
        }

        protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
        {
            int index = 0;
            if (dataBinding)
            {
                if (this.HeaderTemplate != null)
                {
                    TreeListItem container = new TreeListItem(index);
                    this.HeaderTemplate.InstantiateIn(container);
                    Controls.Add(container);
                    index++;
                    container.DataBind();
                } 
                foreach (TreeListNode dataItem in m_nodes)
                {
                    if (this.ItemTemplate != null)
                    {
                        TreeListViewTemplate container = new TreeListViewTemplate(dataItem, index);
                        this.ItemTemplate.InstantiateIn(container);
                        Controls.Add(container);
                        index++;
                        container.DataBind();
                    }
                }
                if (this.FooterTemplate != null)
                {
                    TreeListItem container = new TreeListItem(index);
                    this.FooterTemplate.InstantiateIn(container);
                    Controls.Add(container);
                    index++;
                    container.DataBind();
                }
            }
            return index;

        }

        #endregion

        #region Events




        #endregion

        #region Methods

        public TreeListView()
        {
            m_nodes = new List<TreeListNode>();
            //m_nIndex = 1;
        }

        private void AddNode(TreeListNode parent, TreeListNode child)
        {
            AddNode(parent, child,false);
        }

        private void AddNode(TreeListNode parent, TreeListNode child, bool isLastNode)
        {
            child.ID = m_nIndex;
            child.DisplayID = this.Prefix + "_" + child.ID;
            child.ImageURL = ImageCollapse;
            child.TreeListView = this;
            child.IsLastNode = isLastNode;

            m_nIndex++;
            if (IsShowRootNode || parent!=null)
            {
                m_nodes.Add(child);
            }
            

            if (parent!=null)
            {
                parent.Child.Add(child.DisplayID);
            }

            int nCount = child.ChildNodes.Count;
            for (int i = 0; i < nCount;i++ )
            {
                AddNode(child, (TreeListNode)child.ChildNodes[i],i==nCount-1);
            }

            //foreach (TreeListNode item in child.ChildNodes)
            //{
            //    AddNode(child, item);
            //}
        }

        #endregion
    }
}
